import unittest
import os
import sys
import re
from functools import partial

def modnames(root=os.curdir, walker=os.walk,
        addpath=partial(sys.path.insert, 0)):
    pkg = []
    prevp = ''
    root = os.path.abspath(root)
    if os.path.exists(os.path.join(root, '__init__.py')):
        addpath(os.path.dirname(root))
    for p, ds, fs in walker(root):
        ds[:] = [dn for dn in ds if not dn.startswith('.')]
        if '__init__.py' in fs: # package
            basename = os.path.basename(p)
            if not p.startswith(prevp):
                pkg = []
            pkg.append(basename)
        else:
            pkg = []
            addpath(p)
        names = [fn[:-3] for fn in fs
                if fn.endswith('.py') and not fn.startswith('__')]
        if pkg:
            pkgname = '.'.join(pkg)
            names = ['{0}.{1}'.format(pkgname, name) for name in names]
        for name in names:
            yield  name
        prevp = p

_test_modname = re.compile(r'(test_.*|.*_test|.*Test)$')
def build_suite(root=os.curdir, walker=os.walk):
    '''build test suite from directory hierachy'''
    suite = unittest.TestSuite()
    loader = unittest.TestLoader()
    for name in modnames(root, walker):
        mod = name.split('.')[-1]
        if _test_modname.match(mod):
            tests = loader.loadTestsFromName(name)
            suite.addTests(tests)
    return suite

def main(stream=sys.stdout, verbosity=1):
    suite = build_suite()
    runner = unittest.TextTestRunner(stream=stream, verbosity=verbosity)
    result = runner.run(suite)
    return not result.wasSuccessful()

if __name__ == '__main__':
    sys.exit(main())
